package org.codingq92.hand;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

public class CustomThreadPool {

    private final int coreSize;
    private final int maxSize;
    private final int timeout;
    private final TimeUnit timeUnit;
    private final BlockingQueue<Runnable> coreQueue;

    public CustomThreadPool(int coreSize, int maxSize, int keepAliveTime, TimeUnit timeUnit, BlockingQueue<Runnable> coreQueue) {
        if (coreSize <= 0 || maxSize < coreSize || keepAliveTime < 0 || coreQueue == null) {
            throw new IllegalArgumentException("Invalid thread pool parameters");
        }

        this.coreSize = coreSize;
        this.maxSize = maxSize;
        this.timeout = keepAliveTime;
        this.timeUnit = timeUnit;
        this.coreQueue = coreQueue;
    }

    // 使用 CopyOnWriteArrayList 避免并发修改异常
    private final List<Thread> coreThreadList = new CopyOnWriteArrayList<>();
    private final List<Thread> supThreadList = new CopyOnWriteArrayList<>();

    public void execute(Runnable task) {
        if (coreThreadList.size() < coreSize) {
            Thread thread = new CoreThread(task, "core-thread-" + coreThreadList.size());
            coreThreadList.add(thread);
            thread.start();
            return;
        }

        boolean offered = coreQueue.offer(task);
        if (offered) {
            return;
        }

        if (coreThreadList.size() + supThreadList.size() < maxSize) {
            Thread thread = new SupThread(task, "sup-thread-" + supThreadList.size());
            supThreadList.add(thread);
            thread.setDaemon(true); // 可选：设为守护线程
            thread.start();
            return;
        }

        throw new RuntimeException("任务队列已满");
    }

    private class CoreThread extends Thread {
        private final Runnable task;

        public CoreThread(Runnable task, String name) {
            super(name);
            this.task = task;
        }

        @Override
        public void run() {
            try {
                task.run();
                while (true) {
                    try {
                        Runnable runnable = coreQueue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt(); // 恢复中断状态
                        break;
                    }
                }
            } catch (Throwable t) {
                // 异常处理
                System.err.println("核心线程 [" + getName() + "] 发生异常: " + t.getMessage());
            }
        }
    }

    private class SupThread extends Thread {
        private final Runnable task;

        public SupThread(Runnable task, String name) {
            super(name);
            this.task = task;
        }

        @Override
        public void run() {
            try {
                task.run();
                while (true) {
                    try {
                        Runnable runnable = coreQueue.poll(timeout, timeUnit);
                        if (runnable == null) {
                            break;
                        }
                        runnable.run();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt(); // 恢复中断状态
                        break;
                    }
                }
            } catch (Throwable t) {
                System.err.println("额外线程 [" + getName() + "] 发生异常: " + t.getMessage());
            } finally {
                supThreadList.remove(Thread.currentThread());
                System.out.println("额外线程[" + getName() + "]运行结束");
            }
        }
    }
}
